package org.jeecg.modules.in.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.common.util.DateUtils;
import org.jeecg.constant.CommonConstant;
import org.jeecg.constant.WarehouseConstant;
import org.jeecg.modules.basic.basicSkuInfo.entity.BasicSkuInfo;
import org.jeecg.modules.basic.basicSkuInfo.service.IBasicSkuInfoService;
import org.jeecg.modules.in.entity.InOrderDetail;
import org.jeecg.modules.in.entity.InOrderInfo;
import org.jeecg.modules.in.mapper.InOrderDetailMapper;
import org.jeecg.modules.in.mapper.InOrderInfoMapper;
import org.jeecg.modules.in.service.IInOrderInfoService;
import org.jeecg.modules.inventory.reportLabel.entity.ReportLabel;
import org.jeecg.modules.inventory.reportLabel.service.IReportLabelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.*;

/**
 * @Description: 入库任务
 * @Author: jeecg-boot
 * @Date: 2024-11-29
 * @Version: V1.0
 */
@Service
public class InOrderInfoServiceImpl extends ServiceImpl<InOrderInfoMapper, InOrderInfo> implements IInOrderInfoService {

    @Autowired
    private InOrderInfoMapper inOrderInfoMapper;
    @Autowired
    private InOrderDetailMapper inOrderDetailMapper;
    @Autowired
    private IBasicSkuInfoService basicSkuInfoService;
    @Autowired
    private IReportLabelService reportLabelService;

    @Override
    public void saveWarehousingEntry(InOrderInfo inOrder, List<InOrderDetail> inOrderDetailList) {
        // 生成订单号
        if (StringUtils.isBlank(inOrder.getInOrderCode())) {
            inOrder.setInOrderCode(DateUtils.getToday() + "_" + UUID.randomUUID().toString().replace("-", ""));
        }
        // todo：正常应该做递归确保不重复，暂时先做成用户自己再提交一次 保证订单号不重复
        int orderCodeCount = reportLabelService.count(new LambdaQueryWrapper<ReportLabel>().eq(ReportLabel::getInOrderCode, inOrder.getInOrderCode()));
        Assert.isTrue(orderCodeCount == 0, "出现位未知异常，请重新提交，如问题依旧可联系管理员！");

        Integer skuType = inOrder.getSkuType();
        // 校验输入的品番是否存在
        for (InOrderDetail inOrderDetail : inOrderDetailList) {
            int count = basicSkuInfoService.count(new LambdaQueryWrapper<BasicSkuInfo>()
                    .eq(BasicSkuInfo::getSkuType, skuType)
                    .eq(BasicSkuInfo::getSkuCode, inOrderDetail.getSkuCode()));
            Assert.isFalse(count == 0, "品番编码【%s】不存在！", inOrderDetail.getSkuCode());
        }
        // 保存入库单
        if (null == inOrder.getId()) {
            this.saveMain(inOrder, inOrderDetailList);
        } else {
            this.updateMain(inOrder, inOrderDetailList);
        }
    }

    /**
     * 发布入库单
     *
     * @param id 入库单id
     */
    @Override
    public void releaseWarehousingEntry(String id) {
        InOrderInfo inOrder = inOrderInfoMapper.selectById(id);
        Assert.notNull(inOrder, "后台未查询到对应的入库信息，无法发布入库任务，请联系管理员！");
        Assert.isFalse(WarehouseConstant.EnterWarehouseStatusEnum.RELEASE_END.getCode().equals(inOrder.getStatus()), "请勿重复发布！");
        Assert.isFalse(WarehouseConstant.EnterWarehouseStatusEnum.EXECUTE_END.getCode().equals(inOrder.getStatus()), "入库单已入库完成，无需发布！");
        Assert.isFalse(WarehouseConstant.EnterWarehouseStatusEnum.FORCE_END.getCode().equals(inOrder.getStatus()), "入库单已入库完成，无需发布！");
        Assert.isFalse(WarehouseConstant.EnterWarehouseStatusEnum.DELETE.getCode().equals(inOrder.getStatus()), "入库单已被删除，无法发布！");

        // 更新入库单状态
        inOrder.setReleaseTime(new Date());
        inOrder.setStatus(WarehouseConstant.EnterWarehouseStatusEnum.RELEASE_END.getCode());
        inOrderInfoMapper.updateById(inOrder);
    }

    @Override
    @Transactional
    public void saveMain(InOrderInfo inOrderInfo, List<InOrderDetail> inOrderDetailList) {
        inOrderInfoMapper.insert(inOrderInfo);
        if (CollectionUtils.isNotEmpty(inOrderDetailList)) {
            for (InOrderDetail entity : inOrderDetailList) {
                entity.setInOrderId(inOrderInfo.getId());
                entity.setStatus(CommonConstant.StatusEnum.YES.getCode());
                inOrderDetailMapper.insert(entity);
            }
        }
    }

    @Override
    @Transactional
    public void updateMain(InOrderInfo inOrderInfo, List<InOrderDetail> inOrderDetailList) {
        inOrderInfoMapper.updateById(inOrderInfo);

        //1.先删除子表数据
        inOrderDetailMapper.deleteByMainId(inOrderInfo.getId());

        //2.子表数据重新插入
        if (CollectionUtils.isNotEmpty(inOrderDetailList)) {
            for (InOrderDetail entity : inOrderDetailList) {
                //外键设置
                entity.setInOrderId(inOrderInfo.getId());
                inOrderDetailMapper.insert(entity);
            }
        }
    }

    @Override
    @Transactional
    public void delMain(String id) {
        InOrderInfo inOrderInfo = inOrderInfoMapper.selectById(id);
        Assert.notNull(inOrderInfo, "后台未查询到对应的入库单数据，无法删除，请联系管理员！");
        Assert.isTrue(Objects.equals(inOrderInfo.getStatus(), WarehouseConstant.EnterWarehouseStatusEnum.CREATE_END.getCode()),
                "只有未发布的入库单才可以删除，发布后的入库单不支持删除！");

        inOrderInfo.setStatus(WarehouseConstant.EnterWarehouseStatusEnum.DELETE.getCode());
        inOrderInfoMapper.updateById(inOrderInfo);

        inOrderDetailMapper.update(new InOrderDetail().setStatus(CommonConstant.StatusEnum.NO.getCode()),
                new LambdaQueryWrapper<InOrderDetail>().eq(InOrderDetail::getInOrderId, inOrderInfo.getId()));
    }

    @Override
    @Transactional
    public void delBatchMain(Collection<? extends Serializable> idList) {
        for (Serializable id : idList) {
            InOrderInfo inOrderInfo = inOrderInfoMapper.selectById(id);
            Assert.notNull(inOrderInfo, "后台未查询到对应的入库单数据，无法删除，请联系管理员！");
            Assert.isTrue(Objects.equals(inOrderInfo.getStatus(), WarehouseConstant.EnterWarehouseStatusEnum.CREATE_END.getCode()),
                    "只有未发布的入库单才可以删除，发布后的入库单不支持删除！");

            inOrderInfo.setStatus(WarehouseConstant.EnterWarehouseStatusEnum.DELETE.getCode());
            inOrderInfoMapper.updateById(inOrderInfo);

            inOrderDetailMapper.update(new InOrderDetail().setStatus(CommonConstant.StatusEnum.NO.getCode()),
                    new LambdaQueryWrapper<InOrderDetail>().eq(InOrderDetail::getInOrderId, inOrderInfo.getId()));
        }
    }

}
